﻿using Sunny.UI;
using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace Sunny.FrameDecoder.Demo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            ConsoleLogger.Instance.Level = LogLevel.Trace;
            ConsoleLogger.Instance.Trace("A", "B", "C");
            ConsoleLogger.Instance.Debug("A", "B", "C");
            ConsoleLogger.Instance.Info("A", 3, "C");
            ConsoleLogger.Instance.Warn("A", "B", "C");
            ConsoleLogger.Instance.Error("A", true, "C");
            ConsoleLogger.Instance.Fatal("A", "B", "C");

            ByteArray ba = new ByteArray(100, true);

            byte[] bts = new byte[307200];
            FixedLengthFrameDecoder dc = new FixedLengthFrameDecoder(102400);
            dc.OnDecoder += Dc_OnDecoder;
            dc.Decode(bts);

            ValueCountTimer timer = new ValueCountTimer(TimeSpan.FromSeconds(1));
            timer.Tick = OnTick;

            for (int i = 0; i < 1; i++)
            {
                timer.Add(RandomEx.Next(1000));
                Thread.Sleep(10);
            }

            int aa = GetLength1(ba);
            int bb = GetLength2(ba);
            int cc = GetLength3(ba);

            Console.WriteLine($"{aa} {bb} {cc}");

            Span<int> ints = new int[] { 1, 2, 3, 4 };
            Span<byte> bytes = MemoryMarshal.AsBytes(ints);
            Console.WriteLine(bytes.Length);
            Span<int> ints1 = MemoryMarshal.Cast<byte, int>(bytes);
            Console.WriteLine(ints1.Length);

            ba.Dispose();

            int a = 34;
            int b = 2;
            a = BitHelper.SetFlag(a, b, true);
            Console.WriteLine(a);
            Console.WriteLine(BitHelper.HasFlag(a, b));
            a = BitHelper.SetFlag(a, b, false);
            Console.WriteLine(a);
            Console.WriteLine(BitHelper.HasFlag(a, b));

            TestByteFrameDecoder.TestFixedLengthFrameDecoder();
            TestByteFrameDecoder.TestDelimiterBasedFrameDecoder();
            TestByteFrameDecoder.TestHeaderDelimiterFrameDecoder();
            TestByteFrameDecoder.TestHeaderTailFrameDecoder();
            TestByteFrameDecoder.TestLengthValueFrameDecoder();
            TestByteFrameDecoder.TestTagLengthValueFrameDecoder();
            TestByteFrameDecoder.TestHeaderTagLengthValueTailFrameDecoder();

            TestStringFrameDecoder.TestNMEA0183FrameDecoder();
            TestStringFrameDecoder.TestLineBasedFrameDecoder();

            TestByteFrameDecoder.TestCreateFrame();
        }

        private static void Worker_OnStopped(object sender, EventArgs e)
        {
            Console.WriteLine("WorkEnd");
        }

        private static void Worker_OnWork(object sender, EventArgs e)
        {
            Console.WriteLine(DateTime.Now);
            //Task.Delay(1000).Wait();
        }

        private static void Dc_OnDecoder(object sender, ByteFrameEventArgs e)
        {
            Console.WriteLine(e.Value.Length);
        }

        private static void OnTick(long value)
        {
            Console.WriteLine(value);
        }

        public static int GetLength1(byte[] data)
        {
            return data.Length;
        }

        public static int GetLength2(Span<byte> data)
        {
            return data.Length;
        }

        public static int GetLength3(ReadOnlySpan<byte> data)
        {
            return data.Length;
        }
    }
}